package com.marsdl.textdiff;

import com.marsdl.textdiff.entity.Cell;

public class TextDiff {

    protected boolean isInitialized;

    public Cell[][] LcsObj(String yAxis, String xAxis, Cell[][] scoreTable) {

        char[] yAxisCharArr = yAxis.toCharArray();
        char[] xAxisCharArr = xAxis.toCharArray();

        int yAxisNum = yAxisCharArr.length;
        int xAxisNum = xAxisCharArr.length;

        for (int y = 0; y < yAxisNum; y++) {
            for (int x = 0; x < xAxisNum; x++) {
                System.out.print(y + "," + x + " ");
                if (y == 0 || x == 0) {
                    Cell cell = new Cell(y, x);
                    cell.setScore(0);
                    scoreTable[y][x] = cell;
                    continue;
                }

                if (yAxisCharArr[y] == xAxisCharArr[x]) {
                    Cell cell = new Cell(y, x);
                    cell.setScore(scoreTable[y - 1][x - 1].getScore() + 1);
                    cell.setPrevCell(scoreTable[y - 1][x - 1]);
                    scoreTable[y][x] = cell;
                } else {
                    if (scoreTable[y - 1][x].getScore() > scoreTable[y][x - 1].getScore()) {

                        Cell cell = new Cell(y, x);
                        cell.setScore(scoreTable[y - 1][x].getScore());
                        cell.setPrevCell(scoreTable[y - 1][x]);

                        scoreTable[y][x] = cell;
                        continue;
                    }
                    if (scoreTable[y - 1][x].getScore() < scoreTable[y][x - 1].getScore()) {
                        Cell cell = new Cell(y, x);
                        cell.setScore(scoreTable[y][x - 1].getScore());
                        cell.setPrevCell(scoreTable[y][x - 1]);

                        scoreTable[y][x] = cell;
                    }
                }
            }
            System.out.println();
        }
        return scoreTable;
    }

    public void fillIn(Cell[][] scoreTable) {
        for (int y = 1; y < scoreTable.length; y++) {
            for (int x = 1; x < scoreTable[y].length; x++) {
                Cell currentCell = scoreTable[y][x];
                Cell cellAbove = scoreTable[y - 1][x];
                Cell cellToLeft = scoreTable[y][x - 1];
                Cell cellAboveLeft = scoreTable[y - 1][x - 1];
                fillInCell(currentCell, cellAbove, cellToLeft, cellAboveLeft);
            }
        }
    }

    private static String yAxis = "GCGCAATG";
    private static String xAxis = "GCCCTAGCG";

    public void fillInCell(Cell currentCell, Cell cellAbove, Cell cellToLeft, Cell cellAboveLeft) {
        int aboveScore = cellAbove.getScore();
        int leftScore = cellToLeft.getScore();


        int cellScore = 0;
        Cell cellPointer = null;


        currentCell.setScore(cellScore);
        currentCell.setPrevCell(cellPointer);
    }


    public void traceBack(Cell[][] scoreTable) {
        int num = scoreTable[0].length;
        Cell cell = scoreTable[0][num - 1];
        while (cell.getPrevCell().getScore() != 0) {
            System.out.println(cell.getPrevCell().getScore());
            cell = cell.getPrevCell();
        }
    }

    protected Object getTraceback(Cell[][] scoreTable) {
        StringBuffer lCSBuf = new StringBuffer();
        Cell currentCell = scoreTable[scoreTable.length - 1][scoreTable[0].length - 1];
        while (currentCell.getScore() > 0) {
            Cell prevCell = currentCell.getPrevCell();
            if ((currentCell.getxAxis() - prevCell.getxAxis() == 1 &&
                    currentCell.getyAxis() - prevCell.getyAxis() == 1) &&
                    currentCell.getScore() == prevCell.getScore() + 1) {

                lCSBuf.insert(0, yAxis.charAt(currentCell.getxAxis() - 1));
            }
            currentCell = prevCell;
        }

        return lCSBuf.toString();
    }


    public static void main(String[] args) {
        String yAxis = " GCGCAATG";
        String xAxis = " GCCCTAGCG";
        Cell[][] scoreTable = new Cell[yAxis.length()][xAxis.length()];
//        for (int y = 0; y < scoreTable.length; y++) {
//            for (int x = 0; x < scoreTable[y].length; x++) {
//                Cell cell = new Cell(y, x);
//                cell.setScore(0);
//                scoreTable[y][x] = cell;
//            }
//        }

//        DynamicProgramming dynamicProgramming = new DynamicProgramming();
//        dynamicProgramming.initialize(scoreTable);

        TextDiff textDiff = new TextDiff();
        System.out.println(textDiff.isInitialized);
//        textDiff.fillIn(scoreTable);
//        System.out.println(textDiff.getTraceback(scoreTable));
//        new TextDiff().traceBack(scoreTable);

//        new TextDiff().LcsObj(yAxis, xAxis, scoreTable);
//        for (Cell[] scoreTableYAxis : scoreTable) {
//            for (Cell scoreTableXAxis : scoreTableYAxis) {
//                System.out.print(scoreTableXAxis.getScore());
//            }
//            System.out.println();
//        }
    }
}
